#ifndef __LINKED_LIST_H__
#define __LINKED_LIST_H__

#include <exception>
#include <functional>

using std::exception;
using std::function;

class NotFoundException :
	public exception
{
};

template<typename T>
class LinkedList
{
public:
	class LinkedListNode
	{
	private:
		T value;
		LinkedListNode* next;

	public:
		friend class LinkedList;
		LinkedListNode(T value)
		{
			this->value = value;
			next = nullptr;
		}
	};

private:
	LinkedListNode* first;
	LinkedListNode* last;

public:
	LinkedList()
	{
		first = last = nullptr;
	}

	~LinkedList()
	{
		delete first;
	}

	void append(T in)
	{
		if(last)
		{
			last->next = new LinkedListNode(in);
			last = last->next;
		}
		else
		{
			first = last = new LinkedListNode(in);
		}
	}

	T select(function<bool(T)> selector) const
	{
		LinkedListNode* ptr = first;
		while(ptr)
		{
			if(selector(ptr->value)) return ptr->value;
			ptr = ptr->next;
		}
		throw new NotFoundException();
	}

	void for_each(function<void(T)> proc) const
	{
		LinkedListNode* ptr = first;
		while(ptr)
		{
			proc(ptr->value);
			ptr = ptr->next;
		}
	}
};

#endif